<!--
 * @Descripttion:
 * @version: 1.0.0
 * @Author: htang
 * @Date: 2024-01-22 16:10:54
 * @LastEditors: htang
 * @LastEditTime: 2024-01-26 09:29:54
-->
<template>
  <div class="camera-grap-view jeecg-basic-table">
    <div class="tip">
      <span>视频监控</span>
      <span class="tip-img"></span>
    </div>
    <div class="camvas-view flex p-4">
      <div class="left">
        <a-tree :tree-data="treeData" showLine :multiple="false" @select="onSelect" />
        <!-- <div class="form-node">
          <a-form ref="form" :label-col="{ style: { width: '100px' } }">
            <a-form-item label="水厂名称">
              <a-input placeholder="请输入水厂名称" />
            </a-form-item>
            <a-form-item label="报警时间">
              <a-range-picker
                format="YYYY-MM-DD HH:mm:ss"
                valueFormat="YYYY-MM-DD HH:mm:ss"
                show-time
                style="width: 100%"
                @openChange="onOpenChange"
              />
            </a-form-item>
            <a-form-item label="视频监控数量">
              <a-input placeholder="请输入视频监控数量" />
            </a-form-item>
          </a-form>
        </div> -->
        <!-- <a-table :loading="loading" :dataSource="dataSource" :columns="columns" :pagination="false" size="small" />
        <Pagination
          v-model:current="ipagination.current"
          :pageSize="ipagination.pageSize"
          :total="ipagination.total"
          show-less-items
          @change="handlePageChange"
          :hideOnSinglePage="true"
        /> -->
      </div>
      <div class="right" id="video-node">
        <ErrorText v-show="!isPlay" />
        <div
          id="play"
          v-show="isPlay"
          :style="{
            width: videoParams.width + 'px',
            height: videoParams.height + 'px',
          }"
        ></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { onMounted, onUnmounted, ref, nextTick } from 'vue';
import { cameraListApi } from '/@/api/camera';
import { stationListApi } from '/@/api/station';
import ErrorText from './components/error-text/index.vue';

let loading = ref(false);

let dataSource = ref([]);

let treeData = ref([]);

// 摄像头列表
let cameraList = ref([]);

// 站点列表
let stationList = ref([]);

let columns = ref([
  {
    title: 'ID',
    dataIndex: 'action',
    align: 'center',
  },
  {
    title: '位置',
    dataIndex: 'action',
    align: 'center',
  },
  {
    title: '状态',
    dataIndex: 'action',
    align: 'center',
  },
]);

let ipagination = ref({
  current: 1,
  pageSize: 10,
  pageSizeOptions: ['10', '20', '30'],
  showTotal: (total, range) => {
    return range[0] + '-' + range[1] + ' 共' + total + '条';
  },
  showQuickJumper: true,
  showSizeChanger: true,
  total: 0,
});

let videoParams = ref({
  width: 0,
  height: 0,
});

// 海康码
let hikIndex = ref('44ef985343864cdfb7db5a99a10c2b40');

let oWebControl;
let initCount = 0;
let pubKey = '';
let uuid = '';
// 0 播放，1回放
let playMode = 0;
let isPlay = ref(true);

/**
 * 初始化站点列表
 */
function initStationList() {
  stationListApi().then((res) => {
    stationList.value = res.map((_) => {
      _['title'] = _['name'];
      _['key'] = _['id'];
      _['sign'] = 'station';
      _['children'] = [];
      return _;
    });
    initCameraList();
  });
}

/**
 * 初始化摄像头列表
 */
function initCameraList() {
  treeData.value = [];
  let array = [];
  cameraListApi({}).then((res) => {
    cameraList.value = res.map((_) => {
      _['sign'] = 'camera';
      return _;
    });
    for (let i = 0; i < stationList.value.length; i++) {
      let item = stationList.value[i];
      cameraList.value.map((k) => {
        if (k['stationCode'] == item['stationCode']) {
          k['title'] = k['name'];
          item['children'].push({
            ...k,
          });
        }
      });
      array.push(item);
    }
    treeData.value = array;
    initPlugin();
  });
}

/**
 * 初始化插件
 */
function initPlugin() {
  let playNode: any = document.getElementById('video-node');
  Object.assign(videoParams.value, {
    width: playNode?.clientWidth,
    height: playNode?.clientHeight,
  });
  oWebControl = new WebControl({
    // 指定容器id
    szPluginContainer: 'play',
    // 指定起止端口号，建议使用该值
    iServicePortStart: 15900,
    iServicePortEnd: 15909,
    // 用于IE10使用ActiveX的clsid
    szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11',
    cbConnectSuccess() {
      // 创建WebControl实例成功
      oWebControl
        .JS_StartService('window', {
          // WebControl实例创建成功后需要启动服务
          // 值"./VideoPluginConnect.dll"写死
          dllPath: './VideoPluginConnect.dll',
        })
        .then(
          () => {
            // 启动插件服务成功
            oWebControl.JS_SetWindowControlCallback({
              // 设置消息回调
              // oData 是封装的视频 web 插件回调消息的消息
              cbIntegrationCallBack(oData) {
                console.log(oData);
              },
            });
            let { width, height } = videoParams.value;
            oWebControl.JS_CreateWnd('play', width, height).then(() => {
              // JS_CreateWnd创建视频播放窗口，宽高可设定
              // 创建播放实例成功后初始化
              init();
            });
          },
          () => {
            // 启动插件服务失败
          }
        );
    },
    cbConnectError() {
      // 创建WebControl实例失败
      oWebControl = null;
      isPlay.value = true;
      $('#play').html('插件未启动，正在尝试启动，请稍候...');
      // 程序未启动时执行error函数，采用wakeup来启动程序
      WebControl.JS_WakeUp('VideoWebPlugin://');
      initCount++;
      if (initCount < 3) {
        setTimeout(() => {
          initPlugin();
        }, 3000);
      } else {
        isPlay.value = false;
        $('#play').html(
          '<div>插件启动失败，请检查插件是否安装！' +
            "<a href='https://wrj-heneng.oss-cn-shenzhen.aliyuncs.com/voc/%E6%B5%B7%E5%BA%B7%E6%8F%92%E4%BB%B6/VideoWebPlugin.exe'>点击下载插件安装</a>" +
            '</div>'
        );
      }
    },
    cbConnectClose(bNormalClose) {
      // 异常断开：bNormalClose = false
      // JS_Disconnect正常断开：bNormalClose = true
      bNormalClose = true;
      // 关闭窗体
      oWebControl.JS_HideWnd();
      oWebControl.JS_Disconnect().then((res) => {
        console.log(res);
      });
      oWebControl = null;
    },
  });
}

function init() {
  getPubKey(() => {
    ////////////////////////////////// 请自行修改以下变量值	////////////////////////////////////
    //综合安防管理平台提供的appkey，必填"23182360"
    let appkey = '26521871';
    //综合安防管理平台提供的secret，必填
    let secret = setEncrypt('ZCl9wapWJ1fx5MpDdAPQ');
    //综合安防管理平台IP地址，必填
    let ip = '172.10.1.25';
    //综合安防管理平台端口，若启用HTTPS协议，默认443
    const CAMERA_PORT = 443;
    let port = parseInt(CAMERA_PORT, 10);
    let snapDir = 'D:\\SnapDir'; //抓图存储路径
    let videoDir = 'D:\\VideoDir'; //紧急录像或录像剪辑存储路径
    let layout = '1x1'; //playMode指定模式的布局
    let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互，这里总是填1
    let encryptedFields = 'secret'; //加密字段，默认加密领域为secret
    let showToolbar = 1; //是否显示工具栏，0-不显示，非0-显示
    let showSmart = 1; //是否显示智能信息（如配置移动侦测后画面上的线框），0-不显示，非0-显示
    let buttonIDs = '0,16,256,257,258,259,260,512,513,514,515,516,517,768,769'; //自定义工具条按钮
    ////////////////////////////////// 请自行修改以上变量值	////////////////////////////////////

    oWebControl
      .JS_RequestInterface({
        funcName: 'init',
        argument: JSON.stringify({
          appkey, //API网关提供的appkey
          secret, //API网关提供的secret
          ip, //API网关IP地址
          //初始播放模式：0-预览，1-回放
          //播放模式（决定显示预览还是回放界面）
          playMode: playMode.value,
          port, //端口
          snapDir, //抓图存储路径
          videoDir, //紧急录像或录像剪辑存储路径
          layout, //布局
          enableHTTPS, //是否启用HTTPS协议
          encryptedFields, //加密字段
          showToolbar, //是否显示工具栏
          showSmart, //是否显示智能信息
          buttonIDs, //自定义工具条按钮
        }),
      })
      .then((oData) => {
        // 初始化后resize一次，规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
        let { width, height } = videoParams.value;
        oWebControl.JS_Resize(width, height);
        window.addEventListener('resize', resizeWebControl);
      });
  });
}

//RSA加密
function setEncrypt(value) {
  var encrypt = new JSEncrypt();
  encrypt.setPublicKey(pubKey);
  return encrypt.encrypt(value);
}

function resizeWebControl() {
  let playNode: any = document.getElementById('video-node');
  videoParams.value = {
    //浏览器当前窗口可视区域宽度
    width: playNode.clientWidth,
    //浏览器当前窗口可视区域高度
    height: playNode.clientHeight,
  };
  let { width, height } = videoParams.value;
  oWebControl.JS_Resize(width, height);
}

/**
 * 获取公钥
 */
function getPubKey(callback) {
  oWebControl
    .JS_RequestInterface({
      funcName: 'getRSAPubKey',
      argument: JSON.stringify({
        keyLength: 1024,
      }),
    })
    .then(function (oData) {
      if (oData.responseMsg.data) {
        pubKey = oData.responseMsg.data;
        callback();
      }
    });
}

/**
 * 预览播放
 */
function previewVideo() {
  // 获取输入的监控点编号值，必填
  let cameraIndexCode = hikIndex.value;
  // 主子码流标识：0-主码流，1-子码流
  let streamMode = 0;
  // 传输协议：0-UDP，1-TCP
  let transMode = 1;
  //是否启用GPU硬解，0-不启用，1-启用
  let gpuMode = 0;
  // 播放窗口序号（在2x2以上布局下可指定播放窗口）
  let wndId = -1;

  cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, '');
  cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, '');
  oWebControl.JS_RequestInterface({
    funcName: 'startPreview',
    argument: JSON.stringify({
      cameraIndexCode, //监控点编号
      streamMode, //主子码流标识
      transMode, //传输协议
      gpuMode, //是否开启GPU硬解
      wndId, //可指定播放窗口
    }),
  });
}

/**
 * 关闭海康插件
 */
function closeWindow() {
  // 关闭窗体
  oWebControl.JS_HideWnd();
  oWebControl.JS_Disconnect();
}

/**
 * 选择摄像头播放视频流
 */
function onSelect(data, event) {
  let dataRef = event.node;
  if (dataRef.sign == 'camera') {
    let hik = dataRef['hikIndex'];
    if (hik !== '') {
      hikIndex.value = hik;
      previewVideo();
    } else {
      message.warning('摄像头编码为空');
    }
  }
}

/**
 * 弹出日历和关闭日历的回调
 */
function onOpenChange(bool) {
  if (bool) {
    // 参考：https://www.cnblogs.com/ymhweb/p/15650902.html
    nextTick(() => {
      oWebControl.JS_CuttingPartWindow(0, 95, 225, 320);
    });
  } else {
    oWebControl.JS_RepairPartWindow(0, 95, 225, 320);
  }
}

onMounted(() => {
  initStationList();
});

onUnmounted(() => {
  closeWindow();
});
</script>

<style lang="less" scoped>
.camera-grap-view {
  margin: 12px;
  height: calc(100vh - 144px);
  background: #fff;
  .tip {
    width: 100%;
    height: 44px;
    padding: 0 0 0 43.3px;
    background: url('@/assets/images/img-17.png') no-repeat;
    background-size: 100% 100%;
    line-height: 44px;
    span {
      font-size: 16px;
      color: #fff;
    }
  }
  .camvas-view {
    height: calc(100% - 44px);
    .left {
      width: 305px;
      margin: 0 24px 0 0;
      overflow: hidden;
      overflow-y: scroll;
    }
    .right {
      flex: 1;
    }
  }
}
</style>